/******************************************************************************
 * * contact_number_scrn.c - implementation of contact number screening functions
 *
 * *(C) Copyright 2019 Asr International Ltd.
 * * All Rights Reserved
 * ******************************************************************************/
#include "contact_global.h"

/**
 * Action if pressing contact button on Contacts_Noscreen_Search interface
 * param (in) lv_obj_t *Btn,lv_event_t event
 * return  void
 */
void Contacts_Noscreen_Search_Btn_Contact_Cb(lv_obj_t *Btn,lv_event_t event)
{
    if(LV_EVENT_CLICKED != event)
    {
        return;
    }

    Contacts_List_t *Contact = g_ContactsMng.InterfaceCtrl.Focus;
    UINT8           Len;
    INT8            *Text;

    Len  = strlen(Contact->ContactInfo->Number) + 1;
    Text = (INT8 *)Hal_Mem_Alloc(Len);
    Hal_Mem_Copy(Text, Contact->ContactInfo->Number, Len);
    Contacts_Create_Contacts_Noscreen_Add_Number(Text);
}

/**
 * Create Contacts_Noscreen_Search interface
 * param (in) VOID
 * return  VOID
 */
VOID Contacts_Create_Contacts_Noscreen_Search(VOID)
{
    Contacts_Com_Create_Select_One_Contact(ACT_ID_CONTACTS_NOSCREEN_SEARCH, Contacts_Noscreen_Search_Btn_Contact_Cb);
}

/**
 * Create Contacts_Num_Scrn_List_Full interface
 * param (in) VOID
 * return  VOID
 */
VOID Contacts_Create_Contacts_Num_Scrn_List_Full(VOID)
{
    UI_Status_Desc_t *StatusDesc;
    Nav_Func_List_t  FuncList;
    ACTIVITY_ID      SrcActId = g_ContactsMng.InterfaceCtrl.SrcActId;

    UI_Log_Out(UI_SUB_MODULE_FRAMEWORK, UI_LOG_LEVEL_TRACE_2, "Contacts_Create_Contacts_Num_Scrn_List_Full, SrcActId %d\n", SrcActId);

    StatusDesc = (UI_Status_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Status_Desc_t));
    Hal_Mem_Set(StatusDesc, 0, sizeof(UI_Status_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_NUM_SCRN_LIST_FULL;
    g_ContactsMng.InterfaceCtrl.Ctrl        = (VOID *)StatusDesc;

    StatusDesc->ContLabel.TxtId      = PHONE_TEXT_ID_NUM_SCRN_LIST_FULL;
    StatusDesc->ContLabel.TxtAlign   = LV_LABEL_ALIGN_LEFT;
    StatusDesc->ContLabel.LabelAlign = LV_ALIGN_IN_TOP_LEFT;
    StatusDesc->ContLabelAlign       = LV_ALIGN_IN_TOP_LEFT;

    StatusDesc->ContImg.Img  = LV_SYMBOL_WARNING;
    StatusDesc->ContImgAlign = LV_ALIGN_IN_TOP_RIGHT;

    StatusDesc->KeyFunc = Contacts_Status_Interface_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow    = UI_Status_Create;
    FuncList.OnCreate  = Contacts_Status_Interface_OnCreate;
    FuncList.OnDestroy = Contacts_Interface_OnDestroy;

    if (ACT_ID_CONTACTS_NOSCREEN_ADD_NUMBER == SrcActId)
    {
        Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_NUM_SCRN_LIST_FULL, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
    }
    else
    {
        Nav_Backward_And_Forward(ACT_ID_ANY, SrcActId, ACT_ID_CONTACTS_NUM_SCRN_LIST_FULL, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
    }
}

/**
 * Create Contacts_Num_already_On_List interface
 * param (in) VOID
 * return  VOID
 */
VOID Contacts_Create_Contacts_Num_already_On_List(VOID)
{
    UI_Status_Desc_t *StatusDesc;
    Nav_Func_List_t  FuncList;
    ACTIVITY_ID      SrcActId = g_ContactsMng.InterfaceCtrl.SrcActId;

    UI_Log_Out(UI_SUB_MODULE_FRAMEWORK, UI_LOG_LEVEL_TRACE_2, "Contacts_Create_Contacts_Num_already_On_List, SrcActId %d\n", SrcActId);

    StatusDesc = (UI_Status_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Status_Desc_t));
    Hal_Mem_Set(StatusDesc, 0, sizeof(UI_Status_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_NUM_ALREADY_ON_LIST;
    g_ContactsMng.InterfaceCtrl.Ctrl        = (VOID *)StatusDesc;

    StatusDesc->ContLabel.TxtId      = PHONE_TEXT_ID_NUM_ALREADY_ON;
    StatusDesc->ContLabel.TxtAlign   = LV_LABEL_ALIGN_LEFT;
    StatusDesc->ContLabel.LabelAlign = LV_ALIGN_IN_TOP_LEFT;
    StatusDesc->ContLabelAlign       = LV_ALIGN_IN_TOP_LEFT;

    StatusDesc->ContImg.Img  = LV_SYMBOL_WARNING;
    StatusDesc->ContImgAlign = LV_ALIGN_IN_TOP_RIGHT;

    StatusDesc->KeyFunc = Contacts_Status_Interface_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow    = UI_Status_Create;
    FuncList.OnCreate  = Contacts_Status_Interface_OnCreate;
    FuncList.OnDestroy = Contacts_Interface_OnDestroy;

    if (ACT_ID_CONTACTS_NOSCREEN_ADD_NUMBER == SrcActId)
    {
        Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_NUM_ALREADY_ON_LIST, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
    }
    else
    {
        Nav_Backward_And_Forward(ACT_ID_ANY, SrcActId, ACT_ID_CONTACTS_NUM_ALREADY_ON_LIST, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
    }
}

/**
 * Create Contacts_Noscreen_Added interface
 * param (in) VOID
 * return  VOID
 */
VOID Contacts_Create_Contacts_Noscreen_Added(VOID)
{
    UI_Status_Desc_t *StatusDesc;
    Nav_Func_List_t  FuncList;
    ACTIVITY_ID      SrcActId = g_ContactsMng.InterfaceCtrl.SrcActId;

    UI_Log_Out(UI_SUB_MODULE_FRAMEWORK, UI_LOG_LEVEL_TRACE_2, "Contacts_Create_Contacts_Noscreen_Added, SrcActId %d\n", SrcActId);

    StatusDesc = (UI_Status_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Status_Desc_t));
    Hal_Mem_Set(StatusDesc, 0, sizeof(UI_Status_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_NOSCREEN_ADDED;
    g_ContactsMng.InterfaceCtrl.Ctrl        = (VOID *)StatusDesc;

    StatusDesc->ContLabel.TxtId      = PHONE_TEXT_ID_NUM_ADDED_TO_LIST;
    StatusDesc->ContLabel.TxtAlign   = LV_LABEL_ALIGN_LEFT;
    StatusDesc->ContLabel.LabelAlign = LV_ALIGN_IN_TOP_LEFT;
    StatusDesc->ContLabelAlign       = LV_ALIGN_IN_TOP_LEFT;

    StatusDesc->ContImg.Img  = SYMBOL_CHECKED;
    StatusDesc->ContImgAlign = LV_ALIGN_IN_TOP_RIGHT;

    StatusDesc->KeyFunc = Contacts_Status_Interface_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow      = UI_Status_Create;
    FuncList.OnCreate    = Contacts_Status_Interface_OnCreate;
    FuncList.OnSaveState = Contacts_Interface_OnSaveState;
    FuncList.OnDestroy   = Contacts_Interface_OnDestroy;

    Nav_Backward_And_Forward(ACT_ID_ANY, SrcActId, ACT_ID_CONTACTS_NOSCREEN_ADDED, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
}

/**
 * Insert number to number screening list
 * param (in) Number: INT8 *
 * param (out) CurPos: UINT8 *
 * param (out) EndPos: UINT8 *
 * return  BOOL:FALSE if failure
 */
BOOL Contacts_Insert_Number_To_Num_Scrn_List(INT8 *Number, UINT8 *CurPos, UINT8 *EndPos)
{
    UINT8 i;
    UINT8 Index = 0xFF;
    INT32 CmpRet;
    UINT32 Offset;
    UINT32 Len;

    for (i = 0; i < CONTACTS_MAX_NUM_SCRN_NUMBER; i++)
    {
        if (0 == strlen(g_ContactsMng.NumScrnList[i]))
        {
            break;
        }

        if (0xFF == Index)
        {
            CmpRet = Contacts_Compare_Number(Number, g_ContactsMng.NumScrnList[i]);
            if (0 == CmpRet)
            {
                Contacts_Create_Contacts_Num_already_On_List();
                return(FALSE);
            }
            else if (0 > CmpRet)
            {
                Index = i;
            }
        }
    }

    if (CONTACTS_MAX_NUM_SCRN_NUMBER == i) // list full
    {
        Contacts_Create_Contacts_Num_Scrn_List_Full();
        return(FALSE);
    }
    printf("%s: end %d, index %d\n", __FUNCTION__, i, Index);
    if (0xFF == Index) // insert to the first empty space
    {
        Index = i;
        snprintf(g_ContactsMng.NumScrnList[i], CONTACTS_MAX_NUMBER_LENGTH, "%s", Number);
        Offset = i * CONTACTS_MAX_NUMBER_LENGTH;
        UI_NV_Write_Req(NV_SECTION_UI_NUM_SCRN_LIST, Offset, CONTACTS_MAX_NUMBER_LENGTH, (UINT8 *)Number);
    }
    else
    {
        for (UINT8 j = i;j > Index;j--)
        {
            Hal_Mem_Copy(g_ContactsMng.NumScrnList[j],
                         g_ContactsMng.NumScrnList[j - 1],
                         CONTACTS_MAX_NUMBER_LENGTH);
            printf("%s: copy %d, %s\n", __FUNCTION__, j, g_ContactsMng.NumScrnList[j]);
        }
        snprintf(g_ContactsMng.NumScrnList[Index], CONTACTS_MAX_NUMBER_LENGTH, "%s", Number);
        Offset = Index * CONTACTS_MAX_NUMBER_LENGTH;
        Len    = (i - Index + 1) * CONTACTS_MAX_NUMBER_LENGTH;
        UI_NV_Write_Req(NV_SECTION_UI_NUM_SCRN_LIST, Offset, Len, (UINT8 *)g_ContactsMng.NumScrnList[Index]);
    }
    if (CurPos)
    {
        *CurPos = Index;
    }
    if (EndPos)
    {
        *EndPos = i;
    }
    return(TRUE);
}

/**
 * Callback function for handling key pressed on Contacts_Noscreen_Add_Number interface
 * param (in) Obj: lv_obj_t *
 * param (in) Key_Sta: UI_KEY_STATUS
 * param (in) Key_Val: UI_KEY_VALUE
 * return  UINT8
 */
UINT8 Contacts_Noscreen_Add_Number_Key_Cb(lv_obj_t *Obj, UI_KEY_STATUS Key_Sta,
                                          UI_KEY_VALUE Key_Val)
{
    UINT8                             Ret  = 1;
    INT8                              Char = 0;
    UINT8                             Index;
    UINT8                             i;
    UI_Normal_NoTitle_Label_Ta_Desc_t *Interface =
        (UI_Normal_NoTitle_Label_Ta_Desc_t *)g_ContactsMng.InterfaceCtrl.Ctrl;
    lv_obj_t                          *Ta = Interface->ContTa.TextArea;
    lv_obj_t                          *Label;
    const INT8                        *Text = lv_textarea_get_text(Ta);
    UINT32                            Len1  = strlen(Text);
    UINT32                            Len2;
    UINT8                             Max                = CONTACTS_MAX_NUMBER_LENGTH - 1;
    INT8                              Number[3]          = { 0 };
    UI_Normal_List_Only_Desc_t        *NormalLstOnlyDesc =
        (UI_Normal_List_Only_Desc_t *)g_ContactsMng.InterfaceCtrl.PrevCtrl;
    UINT8                             Count;

    if (KEY_RELEASED == Key_Sta)
    {
        switch (Key_Val)
        {
        case KEY_SOFTRIGHT:
            if (0 == Len1) // back
            {
                Nav_Back(ACT_ID_ANY);
            }
            else // clear
            {
                if (0 == lv_textarea_get_cursor_pos(Ta))
                {
                    /*do nothing if cursor is at the head of text*/
                    break;
                }
                
                lv_textarea_del_char(Ta);
                Len1--;
                if (0 == Len1) // empty in TA
                {
                    Interface->ButtonCont.ButtonM.TxtId = PHONE_TEXT_ID_SEARCH;
                    Label                               = lv_obj_get_child(Interface->ButtonCont.ButtonM.Button, NULL);
                    lv_label_set_text(Label, (INT8 *)lv_lang_get_text(PHONE_TEXT_ID_SEARCH));

                    Interface->ButtonCont.ButtonR.TxtId = PHONE_TEXT_ID_BACK;
                    Label                               = lv_obj_get_child(Interface->ButtonCont.ButtonR.Button, NULL);
                    lv_label_set_text(Label, (INT8 *)lv_lang_get_text(PHONE_TEXT_ID_BACK));
                }
                Len2 = Max - Len1;
                snprintf(Number, 3, "%d", Len2);
                lv_label_set_text(Interface->ContLabelTr.Label, Number);
            }
            break;

        case KEY_0:
        case KEY_1:
        case KEY_2:
        case KEY_3:
        case KEY_4:
        case KEY_5:
        case KEY_6:
        case KEY_7:
        case KEY_8:
        case KEY_9:
        case KEY_ASTERISK:
        case KEY_HASH:
            if (KEY_ASTERISK == Key_Val)
            {
                Char = '*';
            }
            else if (KEY_HASH == Key_Val)
            {
                Char = '#';
            }
            else
            {
                Char = Key_Val - KEY_0 + '0';
            }
            if (Len1 < Max)
            {
                lv_textarea_add_char(Ta, Char);

                if (0 == Len1) // empy in TA before character input
                {
                    Interface->ButtonCont.ButtonM.TxtId = PHONE_TEXT_ID_OK;
                    Label                               = lv_obj_get_child(Interface->ButtonCont.ButtonM.Button, NULL);
                    lv_label_set_text(Label, (INT8 *)lv_lang_get_text(PHONE_TEXT_ID_OK));

                    Interface->ButtonCont.ButtonR.TxtId = PHONE_TEXT_ID_CLEAR;
                    Label                               = lv_obj_get_child(Interface->ButtonCont.ButtonR.Button, NULL);
                    lv_label_set_text(Label, (INT8 *)lv_lang_get_text(PHONE_TEXT_ID_CLEAR));
                }
                Len2 = Max - Len1 - 1;
                snprintf(Number, 3, "%d", Len2);
                lv_label_set_text(Interface->ContLabelTr.Label, Number);
            }
            break;

        case KEY_UP:
        case KEY_DOWN:
        case KEY_LEFT:
        case KEY_RIGHT:
            Ret = 0;
            break;

        case KEY_OK:
            if (0 == Len1) // search contact
            {
                Contacts_Create_Contacts_Noscreen_Search();
                return(Ret);
            }
            else // save number into number screening list
            {
                g_ContactsMng.InterfaceCtrl.SrcActId = ACT_ID_CONTACTS_NOSCREEN_ADD_NUMBER;
                if (FALSE == Contacts_Insert_Number_To_Num_Scrn_List((INT8 *)Text, &Index, &i))
                {
                    return(1);
                }

                /* update Contacts_Noscreen interface */
                if (NULL != NormalLstOnlyDesc)
                {
                    NormalLstOnlyDesc->List.Index = Index;

                    Count = i + 1;

                    for (i = 0; i < NormalLstOnlyDesc->List.ListButtonCnt; i++)
                    {
                        if (NULL != NormalLstOnlyDesc->List.ButtonList[i].BtnTxt)
                        {
                            Hal_Mem_Free(NormalLstOnlyDesc->List.ButtonList[i].BtnTxt);
                            NormalLstOnlyDesc->List.ButtonList[i].BtnTxt = NULL;
                        }
                    }
                    Hal_Mem_Free(NormalLstOnlyDesc->List.ButtonList);

                    NormalLstOnlyDesc->List.ListButtonCnt = Count;
                    Len2                                  = sizeof(UI_Button_Desc_t) *
                                                            NormalLstOnlyDesc->List.ListButtonCnt;
                    NormalLstOnlyDesc->List.ButtonList = (UI_Button_Desc_t *)Hal_Mem_Alloc(Len2);
                    Hal_Mem_Set(NormalLstOnlyDesc->List.ButtonList, 0, Len2);
                    for (i = 0; i < NormalLstOnlyDesc->List.ListButtonCnt; i++)
                    {
                        NormalLstOnlyDesc->List.ButtonList[i].Valid  = TRUE;
                        NormalLstOnlyDesc->List.ButtonList[i].TxtId  = LV_LANG_TXT_ID_NONE;
                        Len1                                         = strlen(g_ContactsMng.NumScrnList[i]) + 1;
                        NormalLstOnlyDesc->List.ButtonList[i].BtnTxt = (INT8 *)Hal_Mem_Alloc(Len1);
                        Hal_Mem_Copy(NormalLstOnlyDesc->List.ButtonList[i].BtnTxt, g_ContactsMng.NumScrnList[i], Len1);
                    }
                    if (0xFF == NormalLstOnlyDesc->BtnBar.ButtonL.ButtonIndex)
                    {
                        NormalLstOnlyDesc->BtnBar.ButtonL.ButtonIndex = 0;
                    }
                }
                else
                {
                    printf("%s: NormalLstOnlyDesc is NULL\n", __FUNCTION__);
                }

                g_ContactsMng.InterfaceCtrl.SrcActId = ACT_ID_CONTACTS_NOSCREEN;
                Contacts_Create_Contacts_Noscreen_Added();
            }
            break;

        case KEY_END:
            Nav_Home(ACT_ID_ANY);
            break;

        default:
            break;
        } /* switch */
    }
    return(Ret);
} /* Contacts_Noscreen_Add_Num_Key_Cb */

/**
 * Callback function for additional actions after Creating Contacts_Noscreen_Add_Number interface
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Noscreen_Add_Number_OnCreate(VOID *Ctrl)
{
    UI_Normal_NoTitle_Label_Ta_Desc_t *Interface = (UI_Normal_NoTitle_Label_Ta_Desc_t *)Ctrl;
    lv_obj_t                          *Label     = Interface->ContLabelTr.Label;
    lv_obj_t                          *Ta        = Interface->ContTa.TextArea;
    const INT8                        *TaTxt     = lv_textarea_get_text(Ta);
    INT8                              Text[3];
    UINT32                            Max = CONTACTS_MAX_NUMBER_LENGTH - 1;
    UINT8                             Len = strlen(TaTxt);

    if (Max < Len)
    {
        /* error */
        return;
    }

    Len = Max - Len;
    sprintf(Text, "%d", Len);
    lv_label_set_text(Label, Text);

    lv_textarea_set_max_length(Ta, Max);

    Ime_Set_Mode(LV_IME_MODE_NUM);
    Ime_Set_SingleMode(TRUE);
}

/**
 * Callback function for restoring state on Contacts_Noscreen_Add_Number interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Noscreen_Add_Number_OnRestoreState(VOID *Ctrl)
{
    UI_Normal_NoTitle_Label_Ta_Desc_t *Interface = (UI_Normal_NoTitle_Label_Ta_Desc_t *)Ctrl;
    lv_obj_t                          *Label     = Interface->ContLabelTr.Label;
    UINT8                             Digit      = strlen(Interface->ContTa.TaTxt);
    INT8                              Text[3]    = { 0 };
    UINT32                            Max        = CONTACTS_MAX_NUMBER_LENGTH - 1;
    lv_obj_t                          *Ta        = Interface->ContTa.TextArea;

    g_ContactsMng.InterfaceCtrl.Ctrl        = Ctrl;
    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_NOSCREEN_ADD_NUMBER;

    if (Max < Digit)
    {
        /* error */
        return;
    }

    Digit = Max - Digit;
    sprintf(Text, "%d", Digit);
    lv_label_set_text(Label, Text);

    lv_textarea_set_max_length(Ta, Max);

    Ime_Set_Mode(LV_IME_MODE_NUM);
    Ime_Set_SingleMode(TRUE);
}

/**
 * Callback function for saving state on Contacts_Noscreen_Add_Number interface before forward to another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Noscreen_Add_Number_OnSaveState(VOID *Ctrl)
{
    UI_Text_Area_Desc_t *ContTa = &(((UI_Normal_NoTitle_Label_Ta_Desc_t *)Ctrl)->ContTa);
    const INT8          *Text;
    UINT8               Len;

    if (0 != strlen(ContTa->TaTxt))
    {
        Hal_Mem_Free(ContTa->TaTxt);
        ContTa->TaTxt = NULL;
    }
    Text = lv_textarea_get_text(ContTa->TextArea);
    Len  = strlen(Text);
    if (0 != Len)
    {
        Len++;
        ContTa->TaTxt = (INT8 *)Hal_Mem_Alloc(Len);
        Hal_Mem_Copy(ContTa->TaTxt, (INT8 *)Text, Len);
    }
    else
    {
        ContTa->TaTxt = "";
    }
}

/**
 * Callback function for destroying Contacts_Noscreen_Add_Number interface which will be popped from stack
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Noscreen_Add_Number_OnDestroy(VOID *Ctrl)
{
    UI_Text_Area_Desc_t *ContTa = &(((UI_Normal_NoTitle_Label_Ta_Desc_t *)Ctrl)->ContTa);

    if (0 != strlen(ContTa->TaTxt))
    {
        Hal_Mem_Free(ContTa->TaTxt);
    }
    Hal_Mem_Free(Ctrl);
}

/**
 * Create Contacts_Noscreen_Add_Number interface
 * param (in) Text: INT8 *
 * return  VOID
 */
VOID Contacts_Create_Contacts_Noscreen_Add_Number(INT8 *Text)
{
    UI_Normal_NoTitle_Label_Ta_Desc_t *Interface;
    Nav_Func_List_t                   FuncList;

    if (NULL == Text)
    {
        /* error */
        return;
    }

    Interface =
        (UI_Normal_NoTitle_Label_Ta_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_NoTitle_Label_Ta_Desc_t));
    Hal_Mem_Set(Interface, 0, sizeof(UI_Normal_NoTitle_Label_Ta_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_NOSCREEN_ADD_NUMBER;
    g_ContactsMng.InterfaceCtrl.Ctrl        = (VOID *)Interface;

    Interface->ContLabelTl.TxtId       = LV_LANG_TXT_ID_NONE;
    Interface->ContLabelTl.TxtAlign    = LV_LABEL_ALIGN_LEFT;
    Interface->ContLabelTl.LabelAlign  = LV_ALIGN_IN_TOP_LEFT;
    Interface->ContLabelTl.SymbolId    = LV_SYMBOL_EDIT;
    Interface->ContLabelTl.SymbolAlign = LV_LABEL_ALIGN_LEFT;

    Interface->ContLabelTr.TxtId      = LV_LANG_TXT_ID_NONE;
    Interface->ContLabelTr.TxtAlign   = LV_LABEL_ALIGN_RIGHT;
    Interface->ContLabelTr.LabelAlign = LV_ALIGN_IN_TOP_RIGHT;

    Interface->ContLabel.TxtId      = PHONE_TEXT_ID_PHONE_NUM;
    Interface->ContLabel.TxtAlign   = LV_LABEL_ALIGN_LEFT;
    Interface->ContLabel.LabelAlign = LV_ALIGN_IN_LEFT_MID;

    Interface->ContTa.TaTxt        = Text;
    Interface->ContTa.TaCursorHide = FALSE;
    Interface->ContTa.TaAlign      = LV_ALIGN_IN_BOTTOM_LEFT;

    Interface->ButtonCont.ButtonL.Valid = FALSE;

    Interface->ButtonCont.ButtonM.Valid = TRUE;
    Interface->ButtonCont.ButtonR.Valid = TRUE;
    if (0 == strlen(Text))
    {
        Interface->ButtonCont.ButtonM.TxtId = PHONE_TEXT_ID_SEARCH;
        Interface->ButtonCont.ButtonR.TxtId = PHONE_TEXT_ID_BACK;
    }
    else
    {
        Interface->ButtonCont.ButtonM.TxtId = PHONE_TEXT_ID_OK;
        Interface->ButtonCont.ButtonR.TxtId = PHONE_TEXT_ID_CLEAR;
    }

    Interface->KeyFunc = Contacts_Noscreen_Add_Number_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow         = UI_Normal_NoTitle_Label_Ta_Create;
    FuncList.OnCreate       = Contacts_Noscreen_Add_Number_OnCreate;
    FuncList.OnRestoreState = Contacts_Noscreen_Add_Number_OnRestoreState;
    FuncList.OnSaveState    = Contacts_Noscreen_Add_Number_OnSaveState;
    FuncList.OnDestroy      = Contacts_Noscreen_Add_Number_OnDestroy;

    if (0 == strlen(Text))
    {
        Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_NOSCREEN_ADD_NUMBER, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
    }
    else // delete Contacts_Noscreen_Search
    {
        Nav_Backward_And_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_NOSCREEN_OPTION, ACT_ID_CONTACTS_NOSCREEN_ADD_NUMBER, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
    }
} /* Contacts_Create_Contacts_Noscreen_Add_Number */

/**
 * Create Contacts_Noscreen_Num_Deleted interface
 * param (in) VOID
 * return  VOID
 */
VOID Contacts_Create_Contacts_Noscreen_Num_Deleted(VOID)
{
    UI_Status_Desc_t *StatusDesc;
    Nav_Func_List_t  FuncList;
    ACTIVITY_ID      SrcActId = g_ContactsMng.InterfaceCtrl.SrcActId;

    UI_Log_Out(UI_SUB_MODULE_FRAMEWORK, UI_LOG_LEVEL_TRACE_2, "Contacts_Create_Contacts_Noscreen_Num_Deleted, SrcActId %d\n", SrcActId);

    StatusDesc = (UI_Status_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Status_Desc_t));
    Hal_Mem_Set(StatusDesc, 0, sizeof(UI_Status_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_NOSCREEN_NUM_DELETED;
    g_ContactsMng.InterfaceCtrl.Ctrl        = (VOID *)StatusDesc;

    StatusDesc->ContLabel.TxtId      = PHONE_TEXT_ID_NUM_DEL_FROM_LIST;
    StatusDesc->ContLabel.TxtAlign   = LV_LABEL_ALIGN_LEFT;
    StatusDesc->ContLabel.LabelAlign = LV_ALIGN_IN_TOP_LEFT;
    StatusDesc->ContLabelAlign       = LV_ALIGN_IN_TOP_LEFT;

    StatusDesc->ContImg.Img  = SYMBOL_CHECKED;
    StatusDesc->ContImgAlign = LV_ALIGN_IN_TOP_RIGHT;

    StatusDesc->KeyFunc = Contacts_Status_Interface_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow    = UI_Status_Create;
    FuncList.OnCreate  = Contacts_Status_Interface_OnCreate;
    FuncList.OnDestroy = Contacts_Interface_OnDestroy;

    Nav_Backward_And_Forward(ACT_ID_ANY, SrcActId, ACT_ID_CONTACTS_NOSCREEN_NUM_DELETED, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
}

/**
 * Callback function for additional actions after Creating Contacts_Noscreen_Delete interface
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Noscreen_Delete_OnCreate(VOID *Ctrl)
{
    UI_Normal_NoTitle_Desc_t *Interface = (UI_Normal_NoTitle_Desc_t *)Ctrl;
    lv_obj_t                 *Label     = Interface->ContenCont.ContLabel.Label;
    INT8                     *Text;
    UINT8                    Len;
    UINT8                    Index = Interface->ButtonBar.ButtonL.ButtonIndex;
    INT8                     *Output;

    Text   = (INT8 *)(lv_lang_get_text(PHONE_TEXT_ID_DEL_NUM_FROM_LIST_Q));
    Len    = strlen(Text) + 2 + CONTACTS_MAX_NUMBER_LENGTH;
    Output = (INT8 *)Hal_Mem_Alloc(Len);
    sprintf(Output, "%s\n%s", Text, g_ContactsMng.NumScrnList[Index]);
    lv_label_set_text(Label, Output);
    Hal_Mem_Free(Output);
}

/**
 * Callback function for restoring state on Contacts_Noscreen_Delete interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Noscreen_Delete_OnRestoreState(VOID *Ctrl)
{
    UI_Normal_NoTitle_Desc_t *Interface = (UI_Normal_NoTitle_Desc_t *)Ctrl;
    lv_obj_t                 *Label     = Interface->ContenCont.ContLabel.Label;
    INT8                     *Text;
    UINT8                    Len;
    UINT8                    Index = Interface->ButtonBar.ButtonL.ButtonIndex;
    INT8                     *Output;

    g_ContactsMng.InterfaceCtrl.Ctrl        = Ctrl;
    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_NOSCREEN_DELETE;

    Text   = (INT8 *)(lv_lang_get_text(PHONE_TEXT_ID_DEL_NUM_FROM_LIST_Q));
    Len    = strlen(Text) + 2 + CONTACTS_MAX_NUMBER_LENGTH;
    Output = (INT8 *)Hal_Mem_Alloc(Len);
    sprintf(Output, "%s\n%s", Text, g_ContactsMng.NumScrnList[Index]);
    lv_label_set_text(Label, Output);
    Hal_Mem_Free(Output);
}

/**
 * Callback function for handling key pressed on Contacts_Noscreen_Delete interface
 * param (in) Obj: lv_obj_t *
 * param (in) Key_Sta: UI_KEY_STATUS
 * param (in) Key_Val: UI_KEY_VALUE
 * return  UINT8
 */
UINT8 Contacts_Noscreen_Delete_Key_Cb(lv_obj_t *Obj, UI_KEY_STATUS Key_Sta, UI_KEY_VALUE Key_Val)
{
    UINT8                      Ret = 1; // not call default key function for List
    UI_Normal_NoTitle_Desc_t   *Interface;
    UINT8                      Index;
    UINT8                      i;
    UINT32                     Len;
    UINT32                     Offset;
    UI_Normal_List_Only_Desc_t *NormalLstOnlyDesc =
        (UI_Normal_List_Only_Desc_t *)g_ContactsMng.InterfaceCtrl.PrevCtrl;
    UINT8                      Count;

    if (KEY_RELEASED == Key_Sta)
    {
        switch (Key_Val)
        {
        case KEY_SOFTRIGHT:
            Nav_Back(ACT_ID_ANY);
            break;

        case KEY_END:
            Nav_Home(ACT_ID_ANY);
            break;

        case KEY_OK:
            Interface = (UI_Normal_NoTitle_Desc_t *)g_ContactsMng.InterfaceCtrl.Ctrl;
            Index     = Interface->ButtonBar.ButtonL.ButtonIndex;
            printf("%s: del index %d\n", __FUNCTION__, Index);
            if (CONTACTS_MAX_NUM_SCRN_NUMBER <= Index)
            {
                /* error */
                break;
            }

            for (i = (Index + 1); i < CONTACTS_MAX_NUM_SCRN_NUMBER; i++)
            {
                if ('\0' == g_ContactsMng.NumScrnList[i][0])
                {
                    break;
                }
                else
                {
                    Hal_Mem_Copy(g_ContactsMng.NumScrnList[i - 1], g_ContactsMng.NumScrnList[i], CONTACTS_MAX_NUMBER_LENGTH);
                }
            }
            Hal_Mem_Set(g_ContactsMng.NumScrnList[i - 1], 0, CONTACTS_MAX_NUMBER_LENGTH);

            Len    = CONTACTS_MAX_NUMBER_LENGTH * (i - Index);
            Offset = CONTACTS_MAX_NUMBER_LENGTH * Index;
            UI_NV_Write_Req(NV_SECTION_UI_NUM_SCRN_LIST, Offset, Len, (UINT8 *)g_ContactsMng.NumScrnList[Index]);

            /* update Contacts_Noscreen interface */
            printf("%s: NormalLstOnlyDesc %p\n", __FUNCTION__, NormalLstOnlyDesc);
            if (NULL != NormalLstOnlyDesc)
            {
                Count = i - 1;

                for (i = 0; i < NormalLstOnlyDesc->List.ListButtonCnt; i++)
                {
                    if (NULL != NormalLstOnlyDesc->List.ButtonList[i].BtnTxt)
                    {
                        Hal_Mem_Free(NormalLstOnlyDesc->List.ButtonList[i].BtnTxt);
                    }
                }
                Hal_Mem_Free(NormalLstOnlyDesc->List.ButtonList);

                NormalLstOnlyDesc->List.Index = 0;

                if (0 == Count) // empty in number screening list after number deleted
                {
                    NormalLstOnlyDesc->List.ListButtonCnt = 1;
                }
                else
                {
                    NormalLstOnlyDesc->List.ListButtonCnt = Count;
                }

                Len = sizeof(UI_Button_Desc_t) *
                      NormalLstOnlyDesc->List.ListButtonCnt;
                NormalLstOnlyDesc->List.ButtonList = (UI_Button_Desc_t *)Hal_Mem_Alloc(Len);
                Hal_Mem_Set(NormalLstOnlyDesc->List.ButtonList, 0, Len);

                if (0 == Count)
                {
                    NormalLstOnlyDesc->List.ButtonList[0].Valid   = TRUE;
                    NormalLstOnlyDesc->List.ButtonList[0].TxtId   = PHONE_TEXT_ID_EMPTY;
                    NormalLstOnlyDesc->BtnBar.ButtonL.ButtonIndex = 0xFF;
                }
                else
                {
                    for (i = 0; i < NormalLstOnlyDesc->List.ListButtonCnt; i++)
                    {
                        NormalLstOnlyDesc->List.ButtonList[i].Valid       = TRUE;
                        NormalLstOnlyDesc->List.ButtonList[i].ButtonIndex = i;
                        NormalLstOnlyDesc->List.ButtonList[i].TxtId       = LV_LANG_TXT_ID_NONE;
                        Len                                               = strlen(g_ContactsMng.NumScrnList[i]) + 1;
                        NormalLstOnlyDesc->List.ButtonList[i].BtnTxt      = (INT8 *)Hal_Mem_Alloc(Len);
                        Hal_Mem_Copy(NormalLstOnlyDesc->List.ButtonList[i].BtnTxt, g_ContactsMng.NumScrnList[i], Len);
                    }
                }
            }

            Contacts_Create_Contacts_Noscreen_Num_Deleted();
            break;

        default:
            break;
        } /* switch */
    }

    return(Ret);
} /* Contacts_Noscreen_Delete_Key_Cb */

/**
 * Create Contacts_Noscreen_Delete interface
 * param (in) Index: UINT8, index in number screening list
 * return  VOID
 */
VOID Contacts_Create_Contacts_Noscreen_Delete(UINT8 Index)
{
    UI_Normal_NoTitle_Desc_t *Interface;
    Nav_Func_List_t          FuncList;

    UI_Log_Out(UI_SUB_MODULE_FRAMEWORK, UI_LOG_LEVEL_TRACE_1, "Contacts_Create_Contacts_Noscreen_Delete, Index %d, Number %s\n", Index, g_ContactsMng.NumScrnList[Index]);

    Interface = (UI_Normal_NoTitle_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_NoTitle_Desc_t));
    Hal_Mem_Set(Interface, 0, sizeof(UI_Normal_NoTitle_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_NOSCREEN_DELETE;
    g_ContactsMng.InterfaceCtrl.Ctrl        = (VOID *)Interface;

    Interface->ContenCont.ContLabel.TxtId      = LV_LANG_TXT_ID_NONE;
    Interface->ContenCont.ContLabel.TxtAlign   = LV_LABEL_ALIGN_LEFT;
    Interface->ContenCont.ContLabel.LabelAlign = LV_ALIGN_IN_TOP_LEFT;
    Interface->ContenCont.ContLabelAlign       = LV_ALIGN_IN_TOP_LEFT;

    Interface->ButtonBar.ButtonL.Valid       = FALSE;
    Interface->ButtonBar.ButtonL.ButtonIndex = Index;

    Interface->ButtonBar.ButtonM.Valid = TRUE;
    Interface->ButtonBar.ButtonM.TxtId = PHONE_TEXT_ID_OK;

    Interface->ButtonBar.ButtonR.Valid = TRUE;
    Interface->ButtonBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;

    Interface->KeyFunc = Contacts_Noscreen_Delete_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow         = UI_Normal_NoTitle_Create;
    FuncList.OnCreate       = Contacts_Noscreen_Delete_OnCreate;
    FuncList.OnRestoreState = Contacts_Noscreen_Delete_OnRestoreState;
    FuncList.OnDestroy      = Contacts_Interface_OnDestroy;

    Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_NOSCREEN_DELETE, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
}

/**
 * Action if pressing add number button on Contacts_Noscreen_Option interface
 * param (in) lv_obj_t *Btn,lv_event_t event
 * return  void
 */
void Contacts_Noscreen_Option_Btn_Add_Num_Cb(lv_obj_t *Btn,lv_event_t event)
{
    if(LV_EVENT_CLICKED != event)
    {
        return;
    }

    Contacts_Create_Contacts_Noscreen_Add_Number("");
}

/**
 * Action if pressing delete number button on Contacts_Noscreen_Option interface
 * param (in) lv_obj_t *Btn,lv_event_t event
 * return  void
 */
void Contacts_Noscreen_Option_Btn_Del_Num_Cb(lv_obj_t *Btn,lv_event_t event)
{
    if(LV_EVENT_CLICKED != event)
    {
        return;
    }

    UI_Normal_List_Only_Desc_t *NormalLstOnlyDesc =
        (UI_Normal_List_Only_Desc_t *)g_ContactsMng.InterfaceCtrl.Ctrl;
    UINT8                      Index = NormalLstOnlyDesc->BtnBar.ButtonL.ButtonIndex;

    g_ContactsMng.InterfaceCtrl.SrcActId = ACT_ID_CONTACTS_NOSCREEN;
    Contacts_Create_Contacts_Noscreen_Delete(Index);
    UI_Log_Out(UI_SUB_MODULE_FRAMEWORK, UI_LOG_LEVEL_TRACE_1, "Contacts_Noscreen_Option_Btn_Del_Num_Cb, Index %d\n", Index);
}

/**
 * Callback function for restoring state on Contacts_Noscreen_Option interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Noscreen_Option_OnRestoreState(VOID *Ctrl)
{
    g_ContactsMng.InterfaceCtrl.Ctrl        = Ctrl;
    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_NOSCREEN_OPTION;
}

/**
 * Create Contacts_Noscreen_Option interface
 * param (in) Index: UINT8, index of the focus number in number screening list, 0xFF invalid
 * return  VOID
 */
VOID Contacts_Create_Contacts_Noscreen_Option(UINT8 Index)
{
    UI_Normal_List_Only_Desc_t        *NormalLstOnlyDesc;
    Nav_Func_List_t                   FuncList;
    UINT32                            Len;

    UI_Log_Out(UI_SUB_MODULE_FRAMEWORK, UI_LOG_LEVEL_TRACE_1, "Contacts_Create_Contacts_Noscreen_Option, Index %d\n", Index);

    NormalLstOnlyDesc =
        (UI_Normal_List_Only_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_List_Only_Desc_t));
    Hal_Mem_Set(NormalLstOnlyDesc, 0, sizeof(UI_Normal_List_Only_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_NOSCREEN_OPTION;
    g_ContactsMng.InterfaceCtrl.Ctrl        = (VOID *)NormalLstOnlyDesc;

    NormalLstOnlyDesc->TitleBar.TxtId      = PHONE_TEXT_ID_NSCREENING;
    NormalLstOnlyDesc->TitleBar.TxtAlign   = LV_LABEL_ALIGN_CENTER;
    NormalLstOnlyDesc->TitleBar.LabelAlign = LV_ALIGN_IN_TOP_LEFT;

    if (0xFF == Index) // empty in number screening list, not delete, only add
    {
        NormalLstOnlyDesc->List.ListButtonCnt = 1;
    }
    else
    {
        NormalLstOnlyDesc->List.ListButtonCnt = 2;
    }
    Len = sizeof(UI_Button_Desc_t) *
          NormalLstOnlyDesc->List.ListButtonCnt;
    NormalLstOnlyDesc->List.ButtonList = (UI_Button_Desc_t *)Hal_Mem_Alloc(Len);
    Hal_Mem_Set(NormalLstOnlyDesc->List.ButtonList, 0, Len);

    NormalLstOnlyDesc->List.ButtonList[0].Valid      = TRUE;
    NormalLstOnlyDesc->List.ButtonList[0].TxtId      = PHONE_TEXT_ID_ADD_NUM;
    NormalLstOnlyDesc->List.ButtonList[0].ReleaseFun = Contacts_Noscreen_Option_Btn_Add_Num_Cb;

    if (0xFF != Index) // empty in number screening list, not delete, only add
    {
        NormalLstOnlyDesc->List.ButtonList[1].Valid      = TRUE;
        NormalLstOnlyDesc->List.ButtonList[1].TxtId      = PHONE_TEXT_ID_DEL_NUM;
        NormalLstOnlyDesc->List.ButtonList[1].ReleaseFun = Contacts_Noscreen_Option_Btn_Del_Num_Cb;
    }

    NormalLstOnlyDesc->BtnBar.ButtonL.Valid       = FALSE;
    NormalLstOnlyDesc->BtnBar.ButtonL.ButtonIndex = Index;

    NormalLstOnlyDesc->BtnBar.ButtonM.Valid = TRUE;
    NormalLstOnlyDesc->BtnBar.ButtonM.TxtId = PHONE_TEXT_ID_SELECT;

    NormalLstOnlyDesc->BtnBar.ButtonR.Valid = TRUE;
    NormalLstOnlyDesc->BtnBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;

    NormalLstOnlyDesc->KeyFunc = Contacts_Normal_List_Interface_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow         = UI_Normal_List_Only_Create;
    FuncList.OnRestoreState = Contacts_Noscreen_Option_OnRestoreState;
    FuncList.OnDestroy      = Contacts_Normal_List_Interface_OnDestroy;

    Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_NOSCREEN_OPTION, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
} /* Contacts_Create_Contacts_Noscreen_Option */

/**
 * Callback function for handling key pressed on Contacts_Noscreen interface
 * param (in) Obj: lv_obj_t *
 * param (in) Key_Sta: UI_KEY_STATUS
 * param (in) Key_Val: UI_KEY_VALUE
 * return  UINT8
 */
UINT8 Contacts_Noscreen_Key_Cb(lv_obj_t *Obj, UI_KEY_STATUS Key_Sta, UI_KEY_VALUE Key_Val)
{
    UINT8                      Ret        = 1; // not call default key function for List
    UI_Normal_List_Only_Desc_t *Interface =
        (UI_Normal_List_Only_Desc_t *)g_ContactsMng.InterfaceCtrl.PrevCtrl;

    if (KEY_RELEASED == Key_Sta)
    {
        switch (Key_Val)
        {
        case KEY_OK:
        case KEY_SOFTLEFT:
            if (0xFF == Interface->BtnBar.ButtonL.ButtonIndex) // empty in number screening list
            {
                Contacts_Create_Contacts_Noscreen_Option(0xFF);
            }
            else
            {
                Contacts_Create_Contacts_Noscreen_Option(Interface->List.Index);
            }
            break;

        case KEY_SOFTRIGHT:
            Nav_Back(ACT_ID_ANY);
            break;

        case KEY_END:
            Nav_Home(ACT_ID_ANY);
            break;

        case KEY_UP:
        case KEY_DOWN:
        case KEY_LEFT:
        case KEY_RIGHT:
            if (0xFF != Interface->BtnBar.ButtonL.ButtonIndex) // not empty in number screening list
            {
                Contacts_Press_Direction_Key_On_List(Key_Val);
                Ret = 0; // call default key function for List
            }
            break;

        default:
            break;
        } /* switch */
    }

    return(Ret);
} /* Contacts_Noscreen_Key_Cb */

/**
 * Callback function for restoring state on Contacts_Noscreen interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Noscreen_OnRestoreState(VOID *Ctrl)
{
    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_NOSCREEN;
}

/**
 * Callback function for destroying state on Contacts_Noscreen interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Noscreen_OnDestroy(VOID *Ctrl)
{
    Contacts_Normal_List_Interface_OnDestroy(Ctrl);
    g_ContactsMng.InterfaceCtrl.PrevCtrl = NULL;
}

/**
 * Create Contacts_Noscreen interface
 * param (in) VOID
 * return  VOID
 */
VOID Contacts_Create_Contacts_Noscreen(VOID)
{
    UI_Normal_List_Only_Desc_t *NormalLstOnlyDesc;
    Nav_Func_List_t            FuncList;
    UINT8                      i;
    UINT8                      Count = 0;
    UINT32                     Len;

    NormalLstOnlyDesc =
        (UI_Normal_List_Only_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_List_Only_Desc_t));
    Hal_Mem_Set(NormalLstOnlyDesc, 0, sizeof(UI_Normal_List_Only_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_NOSCREEN;
    g_ContactsMng.InterfaceCtrl.PrevCtrl    = (VOID *)NormalLstOnlyDesc;

    NormalLstOnlyDesc->TitleBar.TxtId      = PHONE_TEXT_ID_NSCREENING;
    NormalLstOnlyDesc->TitleBar.TxtAlign   = LV_LABEL_ALIGN_CENTER;
    NormalLstOnlyDesc->TitleBar.LabelAlign = LV_ALIGN_IN_TOP_LEFT;

    for (i = 0; i < CONTACTS_MAX_NUM_SCRN_NUMBER; i++)
    {
        if ('\0' == g_ContactsMng.NumScrnList[i][0])
        {
            break;
        }

        Count++;
    }

    if (0 == Count)
    {
        NormalLstOnlyDesc->List.ListButtonCnt = 1;
    }
    else
    {
        NormalLstOnlyDesc->List.ListButtonCnt = Count;
    }
    Len = sizeof(UI_Button_Desc_t) *
          NormalLstOnlyDesc->List.ListButtonCnt;
    NormalLstOnlyDesc->List.ButtonList = (UI_Button_Desc_t *)Hal_Mem_Alloc(Len);
    Hal_Mem_Set(NormalLstOnlyDesc->List.ButtonList, 0, Len);

    if (0 == Count)
    {
        NormalLstOnlyDesc->List.ButtonList[0].Valid   = TRUE;
        NormalLstOnlyDesc->List.ButtonList[0].TxtId   = PHONE_TEXT_ID_EMPTY;
        NormalLstOnlyDesc->BtnBar.ButtonL.ButtonIndex = 0xFF;
    }
    else
    {
        for (i = 0; i < Count; i++)
        {
            NormalLstOnlyDesc->List.ButtonList[i].Valid  = TRUE;
            NormalLstOnlyDesc->List.ButtonList[i].TxtId  = LV_LANG_TXT_ID_NONE;
            Len                                          = strlen(g_ContactsMng.NumScrnList[i]) + 1;
            NormalLstOnlyDesc->List.ButtonList[i].BtnTxt = (INT8 *)Hal_Mem_Alloc(Len);
            Hal_Mem_Copy(NormalLstOnlyDesc->List.ButtonList[i].BtnTxt, g_ContactsMng.NumScrnList[i], Len);
            printf("%s: Count %d, index %d, numbe %s\n",
                   __FUNCTION__, Count, i, g_ContactsMng.NumScrnList[i]);
        }
    }

    NormalLstOnlyDesc->BtnBar.ButtonL.Valid = TRUE;
    NormalLstOnlyDesc->BtnBar.ButtonL.TxtId = PHONE_TEXT_ID_OPT;

    NormalLstOnlyDesc->BtnBar.ButtonM.Valid = FALSE;

    NormalLstOnlyDesc->BtnBar.ButtonR.Valid = TRUE;
    NormalLstOnlyDesc->BtnBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;

    NormalLstOnlyDesc->KeyFunc = Contacts_Noscreen_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow         = UI_Normal_List_Only_Create;
    FuncList.OnRestoreState = Contacts_Noscreen_OnRestoreState;
    FuncList.OnDestroy      = Contacts_Noscreen_OnDestroy;

    Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_NOSCREEN, &FuncList, g_ContactsMng.InterfaceCtrl.PrevCtrl);
} /* Contacts_Create_Contacts_Noscreen */

/**
 * Callback function for additional actions after Creating Contacts_Noscreen_Add interface
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Add_Num_Scrn_OnCreate(VOID *Ctrl)
{
    UI_Normal_NoTitle_Desc_t *Interface = (UI_Normal_NoTitle_Desc_t *)Ctrl;
    lv_obj_t                 *Label     = Interface->ContenCont.ContLabel.Label;
    INT8                     *Text;
    UINT8                    Len;
    INT8                     *Number = g_ContactsMng.InterfaceCtrl.Number;
    INT8                     *Output;

    Text   = (INT8 *)(lv_lang_get_text(PHONE_TEXT_ID_ADD_NUM_SCRLIST_Q));
    Len    = strlen(Text) + 2 + CONTACTS_MAX_NUMBER_LENGTH;
    Output = (INT8 *)Hal_Mem_Alloc(Len);
    sprintf(Output, "%s\n%s", Text, Number);
    lv_label_set_text(Label, Output);
    Hal_Mem_Free(Output);
}

/**
 * Callback function for restoring state on Contacts_Noscreen_Add interface after backward from another activity
 * param (in) Ctrl: VOID *
 * return  VOID
 */
VOID Contacts_Add_Num_Scrn_OnRestoreState(VOID *Ctrl)
{
    UI_Normal_NoTitle_Desc_t *Interface = (UI_Normal_NoTitle_Desc_t *)Ctrl;
    lv_obj_t                 *Label     = Interface->ContenCont.ContLabel.Label;
    INT8                     *Text;
    UINT8                    Len;
    INT8                     *Number = g_ContactsMng.InterfaceCtrl.Number;
    INT8                     *Output;

    g_ContactsMng.InterfaceCtrl.Ctrl        = Ctrl;
    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_ADD_NUM_SCRN;

    Text   = (INT8 *)(lv_lang_get_text(PHONE_TEXT_ID_ADD_NUM_SCRLIST_Q));
    Len    = strlen(Text) + 2 + CONTACTS_MAX_NUMBER_LENGTH;
    Output = (INT8 *)Hal_Mem_Alloc(Len);
    sprintf(Output, "%s\n%s", Text, Number);
    lv_label_set_text(Label, Output);
    Hal_Mem_Free(Output);
}

/**
 * Callback function for handling key pressed on Contacts_Add_Num_Scrn interface
 * param (in) Obj: lv_obj_t *
 * param (in) Key_Sta: UI_KEY_STATUS
 * param (in) Key_Val: UI_KEY_VALUE
 * return  UINT8
 */
UINT8 Contacts_Add_Num_Scrn_Key_Cb(lv_obj_t *Obj, UI_KEY_STATUS Key_Sta, UI_KEY_VALUE Key_Val)
{
    INT8 *Number;

    if (KEY_RELEASED == Key_Sta)
    {
        switch (Key_Val)
        {
        case KEY_SOFTRIGHT:
            Nav_Back(ACT_ID_ANY);
            break;

        case KEY_END:
            Nav_Home(ACT_ID_ANY);
            break;

        case KEY_OK:
            Number                             = g_ContactsMng.InterfaceCtrl.Number;
            g_ContactsMng.InterfaceCtrl.Number = NULL;
            if (NULL == Number)
            {
                printf("%s: Number is NULL\n", __FUNCTION__);
                return(1);
            }

            if (FALSE == Contacts_Insert_Number_To_Num_Scrn_List(Number, NULL, NULL))
            {
                return(1);
            }
            Contacts_Create_Contacts_Noscreen_Added();

            break;

        default:
            break;
        } /* switch */
    }

    return(1);
} /* Contacts_Noscreen_Add_Key_Cb */

/**
 * Create Contacts_Add_Num_Scrn interface
 * param (in) Index: UINT8, index in number screening list
 * return  VOID
 */
VOID Contacts_Create_Contacts_Add_Num_Scrn(VOID)
{
    UI_Normal_NoTitle_Desc_t *Interface;
    Nav_Func_List_t          FuncList;

    Interface = (UI_Normal_NoTitle_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_NoTitle_Desc_t));
    Hal_Mem_Set(Interface, 0, sizeof(UI_Normal_NoTitle_Desc_t));

    g_ContactsMng.InterfaceCtrl.InterfaceId = ACT_ID_CONTACTS_ADD_NUM_SCRN;
    g_ContactsMng.InterfaceCtrl.Ctrl        = (VOID *)Interface;

    Interface->ContenCont.ContLabel.TxtId      = LV_LANG_TXT_ID_NONE;
    Interface->ContenCont.ContLabel.TxtAlign   = LV_LABEL_ALIGN_LEFT;
    Interface->ContenCont.ContLabel.LabelAlign = LV_ALIGN_IN_TOP_LEFT;
    Interface->ContenCont.ContLabelAlign       = LV_ALIGN_IN_TOP_LEFT;

    Interface->ButtonBar.ButtonL.Valid = FALSE;

    Interface->ButtonBar.ButtonM.Valid = TRUE;
    Interface->ButtonBar.ButtonM.TxtId = PHONE_TEXT_ID_OK;

    Interface->ButtonBar.ButtonR.Valid = TRUE;
    Interface->ButtonBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;

    Interface->KeyFunc = Contacts_Add_Num_Scrn_Key_Cb;

    Hal_Mem_Set(&FuncList, 0, sizeof(Nav_Func_List_t));
    FuncList.OnShow         = UI_Normal_NoTitle_Create;
    FuncList.OnCreate       = Contacts_Add_Num_Scrn_OnCreate;
    FuncList.OnRestoreState = Contacts_Add_Num_Scrn_OnRestoreState;
    FuncList.OnDestroy      = Contacts_Interface_OnDestroy;

    Nav_Forward(ACT_ID_ANY, ACT_ID_CONTACTS_ADD_NUM_SCRN, &FuncList, g_ContactsMng.InterfaceCtrl.Ctrl);
}

/**
 * Add phone number to screening list request
 * param (in) SrcActId: UINT16, refers to ACTIVITY_ID in nav.h
 * param (in) Number: INT8 *
 * return  VOID
 */
VOID Contacts_Add_Num_To_Scrn_List_Req(UINT16 SrcActId, INT8 *Number)
{
    g_ContactsMng.InterfaceCtrl.Number   = Number;
    g_ContactsMng.InterfaceCtrl.SrcActId = (ACTIVITY_ID)SrcActId;

    Contacts_Create_Contacts_Add_Num_Scrn();
}

/**
 * Delete phone number from screening list request
 * param (in) SrcActId: UINT16, refers to ACTIVITY_ID in nav.h
 * param (in) Number: INT8 *
 * return  VOID
 */
VOID Contacts_Del_Num_From_Scrn_List_Req(UINT16 SrcActId, INT8 *Number)
{
    UINT8 i;

    printf("%s: number %s\n", __FUNCTION__, Number);

    for (i = 0; i < CONTACTS_MAX_NUM_SCRN_NUMBER; i++)
    {
        if (0 == Contacts_Compare_Number(Number, g_ContactsMng.NumScrnList[i]))
        {
            break;
        }
    }

    if (CONTACTS_MAX_NUM_SCRN_NUMBER == i)
    {
        printf("%s: not found number %s\n", __FUNCTION__, Number);
        return;
    }

    g_ContactsMng.InterfaceCtrl.SrcActId = (ACTIVITY_ID)SrcActId;
    Contacts_Create_Contacts_Noscreen_Delete(i);
}

/**
 * Get number screening list request
 * param (in) VOID
 * return  INT8 *:dyadic array, NV_CONTACTS_MAX_NUMBER_IN_SCRN_LIST_NUM * NV_CONTACTS_MAX_NUMBER_LEN
 */
INT8 *Contacts_Get_Num_Scrn_List_Req(VOID)
{
    return(g_ContactsMng.NumScrnList[0]);
}

/**
 * Oper number screening list request
 * param (in) VOID
 * return  VOID
 */
VOID Contacts_Enter_Num_Scrn_List_Req(VOID)
{
    Contacts_Create_Contacts_Noscreen();
}

/**
 * Judge whether the number is in number screening list
 * param (in) Number: INT8 *, not free
 * return  BOOL
 */
BOOL Contacts_Is_In_Num_Scrn_List(INT8 *Number)
{
    UINT8 i;

    printf("%s: number %s\n", __FUNCTION__, Number);
    if (NULL == Number)
    {
        return(FALSE);
    }

    for (i = 0; i < CONTACTS_MAX_NUM_SCRN_NUMBER; i++)
    {
        printf("%s: %d, %s\n", __FUNCTION__, i, g_ContactsMng.NumScrnList[i]);
        if (0 == Contacts_Compare_Number(Number, g_ContactsMng.NumScrnList[i]))
        {
            return(TRUE);
        }
    }

    return(FALSE);
}
